﻿using DataCollection.Core.Models;
using DataCollection.Infrastructure;
using DataCollection.WinForm.ViewModel;
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.ExtendedProperties;
using DocumentFormat.OpenXml.Office2013.Excel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;

namespace DataCollection.WinForm.Forms
{
    public partial class ReportForm2 : DCBaseForm
    {
        #region 属性

        public ProjectItem SelectedProjectItem = null!;

        /// <summary>
        /// 试压记录编号
        /// </summary>
        public string HistoryNumber = string.Empty;

        /// <summary>
        /// 试压记录
        /// </summary>
        public HistoryModel SelectedHistoryModel = null!;

        /// <summary>
        /// 试压项目
        /// </summary>
        public ProjectModel SelectedProjectModel = null!;

        /// <summary>
        /// 试压模板
        /// </summary>
        public TemplateModel SelectedTemplateModel = null!;

        private double TemplateTotalTime = 0;

        private DateTime StartTime;

        private DateTime EndTime;

        #endregion

        #region 更新模板信息属性

        /// <summary>
        /// 阶段List
        /// </summary>
        List<string> StageList = new List<string>();

        /// <summary> 
        /// 起步阶段压力
        /// </summary>
        double StartStagePressure = -1;

        /// <summary> 
        /// 起步阶段压力上限
        /// </summary>
        double StartStagePressureMax = -1;

        /// <summary> 
        /// 起步阶段压力下限
        /// </summary>
        double StartStagePressureMin = -1;

        /// <summary>
        /// 保留小数位数
        /// </summary>
        readonly private int Decimal = 4;

        /// <summary>
        /// 阶段数量
        /// </summary>
        int StageCount = -1;

        string CurrentStage = string.Empty;

        /// <summary>
        /// 当前阶段总时间
        /// </summary>
        long StageTotalTime = 0;
        #endregion

        #region 保持阶段属性

        /// <summary> 保持阶段压力
        /// 
        /// </summary>
        double HoldingStagePressure;

        /// <summary> 保持阶段压力上限
        /// 
        /// </summary>
        double HoldingStagePressureMax = 0;

        /// <summary> 保持阶段压力下限
        /// 
        /// </summary>
        double HoldingStagePressureMin = 0;

        #endregion

        #region 自定义方法

        /// <summary>
        /// 加载历史记录信息
        /// </summary>
        private void LoadHistoryInfo()
        {
            Dictionary<string, object> where = new Dictionary<string, object>();
            if (SelectedHistoryModel is not null)
            {
                where["number"] = HistoryNumber;
            }
            List<HistoryModel> list = HistoryModel.List(where);
            if (list.Count <= 0)
            {
                Error("未查询到试压记录信息");
            }
            else
            {
                SelectedHistoryModel = list.First();
                DateTime startTime = DateTimeOffset.FromUnixTimeSeconds(SelectedHistoryModel.StartTime).LocalDateTime;
                DateTime endTime = DateTimeOffset.FromUnixTimeSeconds(SelectedHistoryModel.EndTime).LocalDateTime;
                //DatePickerRange1.Value = [startTime, endTime];
                LoadProjectInfo();
            }
        }

        /// <summary>
        /// 加载试压工程信息
        /// </summary>
        public void LoadProjectInfo()
        {
            Dictionary<string, object> where = new Dictionary<string, object>();
            if (SelectedProjectItem is not null)
            {
                where["number"] = SelectedProjectItem.Number;
            }
            List<ProjectModel> list = ProjectModel.List(where);

            if (list.Count <= 0)
            {
                Error("未查询到试压工程信息");
            }
            else
            {
                SelectedProjectModel = list.First();
                if (SelectedProjectModel != null)
                {
                    ProjectNameLabel.Text = SelectedProjectModel.Name;
                    ProjectNumberLabel.Text = SelectedProjectModel.Number.ToString();
                    StakeMarkLabel.Text = SelectedProjectModel.StakeMark;
                    PipeSpecificationLabel.Text = SelectedProjectModel.PipeSpecification;
                    DesignPressureLabel.Text = SelectedProjectModel.DesignPressure.ToString();
                    PipeLengthLabel.Text = SelectedProjectModel.PipeLength;
                    MediumLabel.Text = SelectedProjectModel.Medium;
                    LoadTemplateInfo();
                    this.Invoke(new MethodInvoker(delegate
                    {
                        TimePanel.Enabled = true;
                    }));
                }
            }
        }

        /// <summary>
        /// 加载试压模板信息
        /// </summary>
        private void LoadTemplateInfo()
        {
            Dictionary<string, object> where = new Dictionary<string, object>();
            if (SelectedProjectModel is not null)
            {
                where["number"] = SelectedProjectModel.TemplateID;
            }
            List<TemplateModel> list = TemplateModel.List(where);

            if (list.Count <= 0)
            {
                Error("未查询到试压模板信息");
            }
            else
            {
                SelectedTemplateModel = list.First();
                IntensityPressureLabel.Text = SelectedTemplateModel.IntensityStagePressure.ToString();
                IntensityTimeLabel.Text = SelectedTemplateModel.IntensityStageTime.ToString() + SelectedTemplateModel.IntensityStageTimeUnit;
                IntensityTimeRangeLabel.Text = "0";

                RigorPressureLabel.Text = SelectedTemplateModel.RigorStagePressure.ToString();
                RigorTimeLabel.Text = SelectedTemplateModel.RigorStageTime.ToString() + SelectedTemplateModel.RigorStageTimeUnit;
                RigorTimeRangeLabel.Text = "0";
                double pressure = SelectedTemplateModel.FirstStagePressure;
                List<double> pressureList = new List<double>();
                if (pressure > 0)
                {
                    StageList.Add("first");
                    if (StartStagePressure == -1)
                    {
                        StartStagePressure = Math.Round(pressure, Decimal);
                    }
                    pressureList.Add(pressure);
                    string unit = SelectedTemplateModel.FirstStageTimeUnit;
                    double time = 0;
                    double tmp = 60;
                    if (unit == "小时")
                    {
                        tmp = 3600;
                    }
                    time = SelectedTemplateModel.FirstStageTime * tmp;
                    TemplateTotalTime += time;
                }

                pressure = SelectedTemplateModel.SecondStagePressure;
                if (pressure > 0)
                {
                    StageList.Add("second");
                    if (StartStagePressure == -1)
                    {
                        StartStagePressure = Math.Round(pressure, Decimal);
                    }
                    pressureList.Add(pressure);
                    string unit = SelectedTemplateModel.SecondStageTimeUnit;
                    double time = 0;
                    double tmp = 60;
                    if (unit == "小时")
                    {
                        tmp = 3600;
                    }
                    time = SelectedTemplateModel.SecondStageTime * tmp;
                    TemplateTotalTime += time;
                }

                pressure = SelectedTemplateModel.ThirdStagePressure;
                if (pressure > 0)
                {
                    StageList.Add("third");
                    if (StartStagePressure == -1)
                    {
                        StartStagePressure = Math.Round(pressure, Decimal);
                    }
                    pressureList.Add(pressure);
                    string unit = SelectedTemplateModel.ThirdStageTimeUnit;
                    double time = 0;
                    double tmp = 60;
                    if (unit == "小时")
                    {
                        tmp = 3600;
                    }
                    time = SelectedTemplateModel.ThirdStageTime * tmp;
                    TemplateTotalTime += time;
                }

                pressure = SelectedTemplateModel.IntensityStagePressure;
                if (pressure > 0)
                {
                    StageList.Add("intensity");
                    if (StartStagePressure == -1)
                    {
                        StartStagePressure = Math.Round(pressure, Decimal);
                    }
                    pressureList.Add(pressure);
                    string unit = SelectedTemplateModel.IntensityStageTimeUnit;
                    double time = 0;
                    double tmp = 60;
                    if (unit == "小时")
                    {
                        tmp = 3600;
                    }
                    time = SelectedTemplateModel.IntensityStageTime * tmp;
                    TemplateTotalTime += time;
                }

                pressure = SelectedTemplateModel.RigorStagePressure;
                if (pressure > 0)
                {
                    StageList.Add("rigor");
                    if (StartStagePressure == -1)
                    {
                        StartStagePressure = Math.Round(pressure, Decimal);
                    }
                    pressureList.Add(pressure);
                    string unit = SelectedTemplateModel.RigorStageTimeUnit;
                    double time = 0;
                    double tmp = 60;
                    if (unit == "小时")
                    {
                        tmp = 3600;
                    }
                    time = SelectedTemplateModel.RigorStageTime * tmp;
                    TemplateTotalTime += time;
                }
                TemplateTotalTime += 5;
                StageCount = StageList.Count;
            }
        }


        #endregion

        #region 更新起步阶段信息
        private void UpdateStartStageInfo(string stage)
        {
            if (SelectedTemplateModel is not null)
            {
                CurrentStage = stage;
                string stageString = StageString(stage);
                double multiple = 1;
                int tmp = 60;

                int time = 0;
                string unit = string.Empty;
                if (stage == "first")
                {
                    StartStagePressure = SelectedTemplateModel.FirstStagePressure;
                    unit = SelectedTemplateModel.FirstStageTimeUnit;
                    if (SelectedTemplateModel.FirstStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = SelectedTemplateModel.FirstStageTime;

                }
                else if (stage == "second")
                {
                    StartStagePressure = SelectedTemplateModel.SecondStagePressure;
                    unit = SelectedTemplateModel.SecondStageTimeUnit;
                    if (SelectedTemplateModel.SecondStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = SelectedTemplateModel.SecondStageTime;
                }
                else if (stage == "third")
                {
                    StartStagePressure = SelectedTemplateModel.ThirdStagePressure;
                    unit = SelectedTemplateModel.ThirdStageTimeUnit;
                    if (SelectedTemplateModel.ThirdStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = SelectedTemplateModel.ThirdStageTime;
                }
                else if (stage == "intensity")
                {
                    StartStagePressure = SelectedTemplateModel.IntensityStagePressure;
                    unit = SelectedTemplateModel.IntensityStageTimeUnit;
                    if (SelectedTemplateModel.IntensityStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = SelectedTemplateModel.IntensityStageTime;
                }
                else if (stage == "rigor")
                {
                    StartStagePressure = SelectedTemplateModel.RigorStagePressure;
                    unit = SelectedTemplateModel.RigorStageTimeUnit;
                    if (SelectedTemplateModel.RigorStageTimeUnit == "小时")
                    {
                        multiple = tmp;
                    }
                    time = SelectedTemplateModel.RigorStageTime;
                }

                StartStagePressureMax = Math.Round(StartStagePressure * (1 + (SelectedTemplateModel.ErrorRange / 100.0f)), 3);
                //StartStagePressureMin = Math.Round(StartStagePressure * (1 - (SelectTemplateModel.ErrorRange / 100.0f)), 3);
                StartStagePressureMin = StartStagePressure;
                StageTotalTime = (long)(time * tmp * multiple);

            }
        }

        private string StageString(string stage)
        {
            string stageString = "";
            if (stage == "first")
            {
                stageString = "第一阶段";
            }
            else if (stage == "second")
            {
                stageString = "第二阶段";
            }
            else if (stage == "third")
            {
                stageString = "第三阶段";
            }
            else if (stage == "intensity")
            {
                stageString = "强度段";
            }
            else if (stage == "rigor")
            {
                stageString = "严密段";
            }
            return stageString;
        }

        #endregion

        #region 更新保持阶段信息

        private void UpdateHoldingStageInfo(string stage)
        {
            if (SelectedTemplateModel is not null)
            {
                string stage_estimate_way = string.Empty;
                double stage_estime_value = 0;
                if (stage == "first")
                {
                    stage_estimate_way = SelectedTemplateModel.FirstStageEstimateWay;
                    stage_estime_value = SelectedTemplateModel.FirstStageEstimateValue;
                }
                else if (stage == "second")
                {
                    stage_estimate_way = SelectedTemplateModel.SecondStageEstimateWay;
                    stage_estime_value = SelectedTemplateModel.SecondStageEstimateValue;
                }
                else if (stage == "third")
                {
                    stage_estimate_way = SelectedTemplateModel.ThirdStageEstimateWay;
                    stage_estime_value = SelectedTemplateModel.ThirdStageEstimateValue;
                }
                else if (stage == "intensity")
                {
                    stage_estimate_way = SelectedTemplateModel.IntensityStageEstimateWay;
                    stage_estime_value = SelectedTemplateModel.IntensityStageEstimateValue;
                }
                else if (stage == "rigor")
                {
                    stage_estimate_way = SelectedTemplateModel.RigorStageEstimateWay;
                    stage_estime_value = SelectedTemplateModel.RigorStageEstimateValue;
                }

                if (stage_estimate_way == "固定数值")
                {
                    //HoldingStagePressureMin = HoldingStagePressure - stage_estime_value;
                    HoldingStagePressureMin = HoldingStagePressure;
                    HoldingStagePressureMax = HoldingStagePressure + stage_estime_value;
                }
                else
                {
                    HoldingStagePressureMax = Math.Round(HoldingStagePressure * (1 + (stage_estime_value / 100.0f)), 3);
                    //HoldingStagePressureMin = Math.Round(HoldingStagePressure * (1 - (stage_estime_value / 100.0f)), 3);
                    HoldingStagePressureMin = HoldingStagePressure;
                }
            }
        }

        #endregion

        #region 系统事件
        public ReportForm2()
        {
            InitializeComponent();
            FullScreen = true;
            Header.Text = "生成试压报告";
        }

        private void ReportForm2_Load(object sender, EventArgs e)
        {
            DCSpin(this, "加载数据...", (action) =>
            {
                //LoadHistoryInfo();
            }, null, () =>
            {


            });
        }

        #endregion

        private void CreateDataButton_Click(object sender, EventArgs e)
        {
            //double minValue = 1.13;
            //double maxValue = 2.25;
            //double startTime = 1750753550;
            //double endTime = 1750753615;
            //int pointCount = CalculatePointCount(startTime, endTime, 1);
            //var points = GenerateParabola(minValue, maxValue, startTime, endTime, pointCount);
            //Log.Debug("111");
            //for (int i = 0; i < StageList.Count; i++)
            //{
            //    string stage = StageList[i];
            //    UpdateStartStageInfo(stage);

            //}
        }

        /// <summary>
        /// 根据时间范围和时间间隔计算点数
        /// </summary>
        static int CalculatePointCount(double startTime, double endTime, double interval)
        {
            double duration = endTime - startTime;
            int count = (int)Math.Round(duration / interval) + 1;
            return Math.Max(2, count); // 确保至少有2个点
        }

        /// <summary>
        /// 生成以时间为x轴的抛物线数据点
        /// </summary>
        /// <param name="min">最小值</param>
        /// <param name="max">最大值</param>
        /// <param name="startTime">起始时间(秒)</param>
        /// <param name="endTime">结束时间(秒)</param>
        /// <param name="count">要生成的点数</param>
        /// <returns>包含时间和值的点列表</returns>
        static List<(double time, double value)> GenerateParabola(double min, double max, double startTime, double endTime, int count)
        {
            List<(double time, double value)> points = new List<(double time, double value)>();

            // 抛物线的标准形式: y = a*t^2 + c
            // 我们调整参数使抛物线在t=[startTime,endTime]区间内，y从min(顶点)变化到max
            double duration = endTime - startTime;
            double a = (max - min) / (duration * duration);  // 抛物线的幅度
            double c = min;                                   // 最小值(顶点)

            // 生成均匀分布的时间值并计算对应的y值
            for (int i = 0; i < count; i++)
            {
                double t = startTime + (double)i / (count - 1) * duration;  // 将i映射到[startTime,endTime]区间
                double shiftedT = t - startTime;                              // 转换为以startTime为原点的时间
                double value = Math.Round(a * shiftedT * shiftedT + c, 4);                  // 计算抛物线值
                points.Add((t, value));
            }

            return points;
        }

        private void ProjectNameLabel_DoubleClick(object sender, EventArgs e)
        {
            ManageProjectForm frm = new ManageProjectForm();
            frm.Type = 1;
            frm.Owner = this;
            frm.ShowDialog();
        }

        private void StartDatePicker_ValueChanged(object sender, AntdUI.DateTimeNEventArgs e)
        {
            if (TemplateTotalTime > 4*3600)
            {
                WarnNotification("当前工程试压时间跨度较大，需手动配置各阶段温度");
            }
            DateTime? date = StartDatePicker.Value;
            if (date is not null)
            {
                StartTime = (DateTime)date;
                long timeSpan = Util.Timestamp(StartTime);
                EndTime = Util.ConvertToDateTime((long)(timeSpan + TemplateTotalTime));
                EndTimeLabel.Text = EndTime.ToString("yyyy-MM-dd HH:mm:ss");
            }
        }
    }
}
